/* Esta clase esta pensada para generar n pruebas aleatorias.
 * Con una cantidad m de operaciones con un peso que determina
 * la presencia de una u otra. Puede especificarse el numero de
 * pruebas (n), el numero de operaciones (m), el volumen de datos (k)
 * y la posibilidad de generar un archivo de pruebas o ejecutarlas en
 * caliente */

#ifndef TESTSGENERATOR_H
#define TESTSGENERATOR_H

#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <stdio.h>
#include "heap.h"
#include "fib_heap.h"

class TestsGenerator
{
public:
    TestsGenerator();
    TestsGenerator(long n, long m, long k, long gentestfile, int minrand, int maxrand);
    TestsGenerator(long n, long m, long k, long gentestfile);

    void setNPruebas (long n);
    void setMOperaciones (long m);
    void setKNodos (long k);
    void setGenTestFile(bool value);
    void setnOpHeap(int n);
    void setnOpFHeap(int n);

    /* Para la generacion de claves, se hace un rand
     * de minrandKey a maxrandKey (inclusive). Si estas
     * no se especifican con setRandLimits, el default es
     * del 1 al 1000.
     *
     * Por otra parte, getRandNumber() generara claves
     * con los limites especificados por minrandKey y maxrandKey,
     * salvo que se use getRandNumber(min, max) en cuyo caso
     * seran estos los limites tomados en cuenta */
    void setRandLimits (int min, int max);
    int getRandNumber ();
    int getRandNumber (int min, int max);
    int getRandIndex ();

    /* Esto concierne a la generacion de heaps, la clase puede retornarlos
     * y mantener una copia interna o solo mantener la copia interna */
    Heap* genHeap();
    fib_heap* genFHeap();
    void printHeap(bool all);
    void printFHeap();

    /* Esto es para la generacion de pruebas, en este caso se
     * calcula un vector de probabilidades para
     * cada operacion posible. */
    int genHeapOperationProb();
    int genFHeapOperationProb();

    // Originalmente estos vectores eran dinamicos, se penso en
    // un alcance mayor para esta clase
    int HeapOperationsProb [2]; // Vector de prob
    int FHeapOperationsProb [2]; // Vector de prob

    Heap* heap;
    fib_heap* fheap;

    bool runHeapTest();
    bool runFHeapTest();

private:
    long n_pruebas;
    long m_operaciones;
    long k_nodos;
    bool GENTESTFILE;

    int probExt; // Probabilidad de Extraer
    int probDecr; // Probabilidad de Insertar

    int nopHeap; // # operaciones en heap
    int nopFHeap; // # operaciones en fib_heap

    int randKey;
    int minrandKey;
    int maxrandKey;

    void execHeapOp(int operIndex);
    void execFHeapOp(int operIndex, double &t_resta);

    /* Funciones para medir el tiempo de ejecucion */
    double timeval_diff (struct timeval *a, struct timeval *b);
};

#endif // TESTSGENERATOR_H
